/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <gtest/gtest.h>
#include <test_utilities/test_base.h>
#include <mc/engine.h>
#include <mc/common.h>
#include <thread>
#include <chrono>
#include "../../../drivers/internal/manager.h"

namespace drivers {
namespace internal {
namespace test {

class ManagerTest : public mc::test::TestWithEngine {
protected:
    void SetUp() override {
        TestWithEngine::SetUp();
        // 清空管理器状态，确保测试隔离
        auto& manager = dev::device_manager::get_instance();
        manager.clear_all();
    }

    void TearDown() override {
        // 清理测试数据
        auto& manager = dev::device_manager::get_instance();
        manager.clear_all();
        TestWithEngine::TearDown();
    }

    mc::mutable_dict create_chip_csr() {
        mc::mutable_dict csr;
        csr["Address"] = static_cast<uint32_t>(0x70);
        csr["OffsetWidth"] = static_cast<uint8_t>(1);
        csr["AddrWidth"] = static_cast<uint8_t>(1);
        csr["WriteTmout"] = static_cast<uint32_t>(100);
        csr["ReadTmout"] = static_cast<uint32_t>(100);
        return csr;
    }

    mc::mutable_dict create_bus_csr() {
        mc::mutable_dict csr;
        csr["Id"] = static_cast<uint8_t>(1);
        return csr;
    }
};

// ========================= 单例模式测试 =========================

TEST_F(ManagerTest, GetInstance_Singleton) {
    // 测试单例模式：多次调用应返回同一个实例
    auto& manager1 = dev::device_manager::get_instance();
    auto& manager2 = dev::device_manager::get_instance();
    
    EXPECT_EQ(&manager1, &manager2);
}

TEST_F(ManagerTest, GetInstance_ThreadSafe) {
    // 测试多线程环境下的单例安全性
    std::vector<std::thread> threads;
    std::vector<dev::device_manager*> instances;
    std::mutex mutex;
    
    for (int i = 0; i < 10; ++i) {
        threads.emplace_back([&mutex, &instances]() {
            auto& manager = dev::device_manager::get_instance();
            std::lock_guard<std::mutex> lock(mutex);
            instances.push_back(&manager);
        });
    }
    
    for (auto& thread : threads) {
        thread.join();
    }
    
    // 所有线程应该获取到同一个实例
    for (size_t i = 1; i < instances.size(); ++i) {
        EXPECT_EQ(instances[0], instances[i]);
    }
}

// ========================= Chip 创建测试 =========================

TEST_F(ManagerTest, CreateChip_Success) {
    auto& manager = dev::device_manager::get_instance();
    auto csr = create_chip_csr();
    
    // 测试创建各种类型的chip
    auto pca9545 = manager.create_chip("test_pca9545", "Pca9545", csr);
    EXPECT_NE(pca9545, nullptr);
    
    auto pca9555 = manager.create_chip("test_pca9555", "Pca9555", csr);
    EXPECT_NE(pca9555, nullptr);
    
    auto chip = manager.create_chip("test_chip", "Chip", csr);
    EXPECT_NE(chip, nullptr);
    
    auto lm75 = manager.create_chip("test_lm75", "Lm75", csr);
    EXPECT_NE(lm75, nullptr);
    
    auto ads78 = manager.create_chip("test_ads78", "Ads78", csr);
    EXPECT_NE(ads78, nullptr);
    
    auto eeprom = manager.create_chip("test_eeprom", "Eeprom", csr);
    EXPECT_NE(eeprom, nullptr);
}

TEST_F(ManagerTest, CreateChip_EmptyCsrData) {
    auto& manager = dev::device_manager::get_instance();
    mc::mutable_dict empty_csr;
    
    // 空CSR数据应该抛出异常
    auto chip = manager.create_chip("test_chip", "Chip", empty_csr);
    EXPECT_EQ(chip, nullptr);
}

TEST_F(ManagerTest, CreateChip_UnsupportedType) {
    auto& manager = dev::device_manager::get_instance();
    auto csr = create_chip_csr();
    
    // 不支持的chip类型应该返回nullptr
    auto chip = manager.create_chip("test_unknown", "UnknownChip", csr);
    EXPECT_EQ(chip, nullptr);
}

TEST_F(ManagerTest, CreateChip_DuplicateName) {
    auto& manager = dev::device_manager::get_instance();
    auto csr = create_chip_csr();
    
    // 第一次创建应该成功
    auto chip1 = manager.create_chip("test_chip", "Chip", csr);
    EXPECT_NE(chip1, nullptr);
    
    // 使用相同名称再次创建应该返回同一个对象
    auto chip2 = manager.create_chip("test_chip", "Chip", csr);
    EXPECT_NE(chip2, nullptr);
    EXPECT_EQ(chip1, chip2);
}

TEST_F(ManagerTest, CreateChip_InitFailure) {
    auto& manager = dev::device_manager::get_instance();
    mc::mutable_dict invalid_csr;
    // 创建无效的CSR数据，导致init失败
    invalid_csr["InvalidField"] = "InvalidValue";
    
    // init失败时应该返回nullptr
    auto chip = manager.create_chip("test_chip", "Chip", invalid_csr);
    // 注意：由于Chip的init可能接受空字典，这个测试可能不会失败
    // 但至少验证了异常处理路径
}

// ========================= Bus 创建测试 =========================

TEST_F(ManagerTest, CreateBus_Success) {
    auto& manager = dev::device_manager::get_instance();
    auto csr = create_bus_csr();
    
    // 测试创建各种类型的bus
    auto i2c = manager.create_bus("test_i2c", "I2c", csr);
    EXPECT_NE(i2c, nullptr);
    
    auto hisport = manager.create_bus("test_hisport", "Hisport", csr);
    EXPECT_NE(hisport, nullptr);
    
    auto i2c_mux = manager.create_bus("test_i2c_mux", "I2cMux", csr);
    EXPECT_NE(i2c_mux, nullptr);
}

TEST_F(ManagerTest, CreateBus_EmptyCsrData) {
    auto& manager = dev::device_manager::get_instance();
    mc::mutable_dict empty_csr;
    
    // 空CSR数据应该抛出异常
    auto bus = manager.create_bus("test_bus", "I2c", empty_csr);
    EXPECT_EQ(bus, nullptr);
}

TEST_F(ManagerTest, CreateBus_UnsupportedType) {
    auto& manager = dev::device_manager::get_instance();
    auto csr = create_bus_csr();
    
    // 不支持的bus类型应该返回nullptr
    auto bus = manager.create_bus("test_unknown", "UnknownBus", csr);
    EXPECT_EQ(bus, nullptr);
}

TEST_F(ManagerTest, CreateBus_DuplicateName) {
    auto& manager = dev::device_manager::get_instance();
    auto csr = create_bus_csr();
    
    // 第一次创建应该成功
    auto bus1 = manager.create_bus("test_bus", "I2c", csr);
    EXPECT_NE(bus1, nullptr);
    
    // 使用相同名称再次创建应该返回同一个对象
    auto bus2 = manager.create_bus("test_bus", "I2c", csr);
    EXPECT_NE(bus2, nullptr);
    EXPECT_EQ(bus1, bus2);
}

// ========================= 查找对象测试 =========================

TEST_F(ManagerTest, FindObject_Chip_Success) {
    auto& manager = dev::device_manager::get_instance();
    auto csr = create_chip_csr();
    
    // 先创建chip
    auto chip = manager.create_chip("test_chip", "Chip", csr);
    ASSERT_NE(chip, nullptr);
    
    // 查找chip应该成功
    auto found = manager.find_object("test_chip", dev::object_type::chip);
    EXPECT_TRUE(std::holds_alternative<std::shared_ptr<dev::chip_base>>(found));
    
    auto found_chip = std::get<std::shared_ptr<dev::chip_base>>(found);
    EXPECT_NE(found_chip, nullptr);
    EXPECT_EQ(chip, found_chip);
}

TEST_F(ManagerTest, FindObject_Chip_NotFound) {
    auto& manager = dev::device_manager::get_instance();
    
    // 查找不存在的chip应该返回nullptr
    auto found = manager.find_object("non_existent_chip", dev::object_type::chip);
    EXPECT_TRUE(std::holds_alternative<std::shared_ptr<dev::chip_base>>(found));
    
    auto found_chip = std::get<std::shared_ptr<dev::chip_base>>(found);
    EXPECT_EQ(found_chip, nullptr);
}

TEST_F(ManagerTest, FindObject_Bus_Success) {
    auto& manager = dev::device_manager::get_instance();
    auto csr = create_bus_csr();
    
    // 先创建bus
    auto bus = manager.create_bus("test_bus", "I2c", csr);
    ASSERT_NE(bus, nullptr);
    
    // 查找bus应该成功
    auto found = manager.find_object("test_bus", dev::object_type::bus);
    EXPECT_TRUE(std::holds_alternative<std::shared_ptr<dev::bus_base>>(found));
    
    auto found_bus = std::get<std::shared_ptr<dev::bus_base>>(found);
    EXPECT_NE(found_bus, nullptr);
    EXPECT_EQ(bus, found_bus);
}

TEST_F(ManagerTest, FindObject_Bus_NotFound) {
    auto& manager = dev::device_manager::get_instance();
    
    // 查找不存在的bus应该返回nullptr
    auto found = manager.find_object("non_existent_bus", dev::object_type::bus);
    EXPECT_TRUE(std::holds_alternative<std::shared_ptr<dev::chip_base>>(found));
    
    auto found_chip = std::get<std::shared_ptr<dev::chip_base>>(found);
    EXPECT_EQ(found_chip, nullptr);
}

TEST_F(ManagerTest, FindObject_InvalidType) {
    auto& manager = dev::device_manager::get_instance();
    
    // 使用无效的类型应该返回nullptr
    // 注意：object_type 只有 chip 和 bus，这里测试默认分支
    // 由于没有其他类型，这个测试主要验证异常处理
    auto found = manager.find_object("test", dev::object_type::chip);
    EXPECT_TRUE(std::holds_alternative<std::shared_ptr<dev::chip_base>>(found));
}

// ========================= 删除对象测试 =========================

TEST_F(ManagerTest, RemoveObject_Chip_Success) {
    auto& manager = dev::device_manager::get_instance();
    auto csr = create_chip_csr();
    
    // 先创建chip
    auto chip = manager.create_chip("test_chip", "Chip", csr);
    ASSERT_NE(chip, nullptr);
    
    // 删除chip应该成功
    bool result = manager.remove_object("test_chip", dev::object_type::chip);
    EXPECT_TRUE(result);
    
    // 再次查找应该找不到
    auto found = manager.find_object("test_chip", dev::object_type::chip);
    auto found_chip = std::get<std::shared_ptr<dev::chip_base>>(found);
    EXPECT_EQ(found_chip, nullptr);
}

TEST_F(ManagerTest, RemoveObject_Chip_NotFound) {
    auto& manager = dev::device_manager::get_instance();
    
    // 删除不存在的chip应该返回false
    bool result = manager.remove_object("non_existent_chip", dev::object_type::chip);
    EXPECT_FALSE(result);
}

TEST_F(ManagerTest, RemoveObject_Bus_Success) {
    auto& manager = dev::device_manager::get_instance();
    auto csr = create_bus_csr();
    
    // 先创建bus
    auto bus = manager.create_bus("test_bus", "I2c", csr);
    ASSERT_NE(bus, nullptr);
    
    // 删除bus应该成功
    bool result = manager.remove_object("test_bus", dev::object_type::bus);
    EXPECT_TRUE(result);
    
    // 再次查找应该找不到
    auto found = manager.find_object("test_bus", dev::object_type::bus);
    auto found_chip = std::get<std::shared_ptr<dev::chip_base>>(found);
    EXPECT_EQ(found_chip, nullptr);
}

TEST_F(ManagerTest, RemoveObject_Bus_NotFound) {
    auto& manager = dev::device_manager::get_instance();
    
    // 删除不存在的bus应该返回false
    bool result = manager.remove_object("non_existent_bus", dev::object_type::bus);
    EXPECT_FALSE(result);
}

// ========================= 清空所有对象测试 =========================

TEST_F(ManagerTest, ClearAll_Success) {
    auto& manager = dev::device_manager::get_instance();
    auto chip_csr = create_chip_csr();
    auto bus_csr = create_bus_csr();
    
    // 创建多个对象
    auto chip1 = manager.create_chip("chip1", "Chip", chip_csr);
    auto chip2 = manager.create_chip("chip2", "Chip", chip_csr);
    auto bus1 = manager.create_bus("bus1", "I2c", bus_csr);
    auto bus2 = manager.create_bus("bus2", "I2c", bus_csr);
    
    ASSERT_NE(chip1, nullptr);
    ASSERT_NE(chip2, nullptr);
    ASSERT_NE(bus1, nullptr);
    ASSERT_NE(bus2, nullptr);
    
    // 清空所有对象
    manager.clear_all();
    
    // 验证所有对象都被删除
    auto found_chip1 = manager.find_object("chip1", dev::object_type::chip);
    auto found_chip2 = manager.find_object("chip2", dev::object_type::chip);
    auto found_bus1 = manager.find_object("bus1", dev::object_type::bus);
    auto found_bus2 = manager.find_object("bus2", dev::object_type::bus);
    
    EXPECT_EQ(std::get<std::shared_ptr<dev::chip_base>>(found_chip1), nullptr);
    EXPECT_EQ(std::get<std::shared_ptr<dev::chip_base>>(found_chip2), nullptr);
    EXPECT_EQ(std::get<std::shared_ptr<dev::chip_base>>(found_bus1), nullptr);
    EXPECT_EQ(std::get<std::shared_ptr<dev::chip_base>>(found_bus2), nullptr);
}

TEST_F(ManagerTest, ClearAll_Empty) {
    auto& manager = dev::device_manager::get_instance();
    
    // 清空空表应该不会出错
    manager.clear_all();
    
    // 验证表确实是空的
    const auto& chip_table = manager.get_chip_table();
    const auto& bus_table = manager.get_bus_table();
    
    EXPECT_EQ(chip_table.size(), 0);
    EXPECT_EQ(bus_table.size(), 0);
}

// ========================= 获取表测试 =========================

TEST_F(ManagerTest, GetChipTable_Success) {
    auto& manager = dev::device_manager::get_instance();
    auto csr = create_chip_csr();
    
    // 创建多个chip
    auto chip1 = manager.create_chip("chip1", "Chip", csr);
    auto chip2 = manager.create_chip("chip2", "Chip", csr);
    
    ASSERT_NE(chip1, nullptr);
    ASSERT_NE(chip2, nullptr);
    
    // 获取chip表
    const auto& chip_table = manager.get_chip_table();
    
    EXPECT_EQ(chip_table.size(), 2);
    EXPECT_NE(chip_table.find("chip1"), chip_table.end());
    EXPECT_NE(chip_table.find("chip2"), chip_table.end());
}

TEST_F(ManagerTest, GetBusTable_Success) {
    auto& manager = dev::device_manager::get_instance();
    auto csr = create_bus_csr();
    
    // 创建多个bus
    auto bus1 = manager.create_bus("bus1", "I2c", csr);
    auto bus2 = manager.create_bus("bus2", "I2c", csr);
    
    ASSERT_NE(bus1, nullptr);
    ASSERT_NE(bus2, nullptr);
    
    // 获取bus表
    const auto& bus_table = manager.get_bus_table();
    
    EXPECT_EQ(bus_table.size(), 2);
    EXPECT_NE(bus_table.find("bus1"), bus_table.end());
    EXPECT_NE(bus_table.find("bus2"), bus_table.end());
}

// ========================= 并发测试 =========================

TEST_F(ManagerTest, ConcurrentCreate) {
    auto& manager = dev::device_manager::get_instance();
    auto chip_csr = create_chip_csr();
    auto bus_csr = create_bus_csr();
    
    std::vector<std::thread> threads;
    std::atomic<int> success_count{0};
    
    // 创建多个线程同时创建对象
    for (int i = 0; i < 10; ++i) {
        threads.emplace_back([&manager, &chip_csr, &bus_csr, i, &success_count]() {
            std::string chip_name = "chip_" + std::to_string(i);
            std::string bus_name = "bus_" + std::to_string(i);
            
            auto chip = manager.create_chip(chip_name, "Chip", chip_csr);
            auto bus = manager.create_bus(bus_name, "I2c", bus_csr);
            
            if (chip && bus) {
                success_count++;
            }
        });
    }
    
    for (auto& thread : threads) {
        thread.join();
    }
    
    // 验证所有对象都创建成功
    EXPECT_EQ(success_count.load(), 10);
    
    const auto& chip_table = manager.get_chip_table();
    const auto& bus_table = manager.get_bus_table();
    
    EXPECT_EQ(chip_table.size(), 10);
    EXPECT_EQ(bus_table.size(), 10);
}

TEST_F(ManagerTest, ConcurrentFind) {
    auto& manager = dev::device_manager::get_instance();
    auto chip_csr = create_chip_csr();
    
    // 先创建对象
    auto chip = manager.create_chip("test_chip", "Chip", chip_csr);
    ASSERT_NE(chip, nullptr);
    
    std::vector<std::thread> threads;
    std::atomic<int> found_count{0};
    
    // 创建多个线程同时查找对象
    for (int i = 0; i < 20; ++i) {
        threads.emplace_back([&manager, &found_count]() {
            auto found = manager.find_object("test_chip", dev::object_type::chip);
            auto found_chip = std::get<std::shared_ptr<dev::chip_base>>(found);
            if (found_chip) {
                found_count++;
            }
        });
    }
    
    for (auto& thread : threads) {
        thread.join();
    }
    
    // 所有线程都应该找到对象
    EXPECT_EQ(found_count.load(), 20);
}

} // namespace test
} // namespace internal
} // namespace drivers
